package com.zt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zt.dto.CouponCreateRequest;
import com.zt.dto.CouponQueryRequest;
import com.zt.entity.Coupons;
import com.zt.enums.CouponStatus;
import com.zt.enums.CouponType;
import com.zt.service.CouponCacheService;
import com.zt.service.AdminCouponsService;
import com.zt.service.AdminCouponCacheService;
import com.zt.mapper.CouponsMapper;
import com.zt.vo.CouponVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author unmai
* @description 针对表【coupons(优惠券表)】的数据库操作Service实现
* @createDate 2025-04-25 13:45:46
*/
@Service
@Slf4j
public class CouponsServiceImpl extends ServiceImpl<CouponsMapper, Coupons>
    implements AdminCouponsService{

    @Autowired
    private CouponCacheService couponCacheService;

    @Autowired
    private AdminCouponCacheService adminCouponCacheService;

    @Override
    public IPage<CouponVO> pageCoupons(CouponQueryRequest request) {
        // 构建查询条件
        LambdaQueryWrapper<Coupons> queryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(request.getTitle())) {
            queryWrapper.like(Coupons::getTitle, request.getTitle());
        }

        if (request.getType() != null) {
            queryWrapper.eq(Coupons::getType, request.getType());
        }

        if (request.getStatus() != null) {
            queryWrapper.eq(Coupons::getStatus, request.getStatus());
        }

        if (request.getStartTimeBegin() != null) {
            queryWrapper.ge(Coupons::getStartTime, request.getStartTimeBegin());
        }

        if (request.getStartTimeEnd() != null) {
            queryWrapper.le(Coupons::getStartTime, request.getStartTimeEnd());
        }

        if (request.getEndTimeBegin() != null) {
            queryWrapper.ge(Coupons::getEndTime, request.getEndTimeBegin());
        }

        if (request.getEndTimeEnd() != null) {
            queryWrapper.le(Coupons::getEndTime, request.getEndTimeEnd());
        }

        // 按创建时间倒序
        queryWrapper.orderByDesc(Coupons::getId);

        // 分页查询
        Page<Coupons> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<Coupons> couponPage = this.page(page, queryWrapper);

        // 转换为VO
        IPage<CouponVO> voPage = new Page<>();
        BeanUtils.copyProperties(couponPage, voPage);

        List<CouponVO> voList = couponPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    @Transactional
    public Integer createCoupon(CouponCreateRequest request) {
        // 验证优惠券模式
        validateCouponRequest(request);

        // 创建优惠券对象
        Coupons coupon = new Coupons();
        BeanUtils.copyProperties(request, coupon);

        // 设置默认状态为未激活
        coupon.setStatus(CouponStatus.INACTIVE.getCode());

        // 保存到数据库
        this.save(coupon);

        // 只保留coupons:键的缓存 - 禁用其他缓存操作
        // couponCacheService.cacheCoupon(coupon);

        // 如果设置了总数量，缓存库存 - 已禁用
        // if (request.getTotalCount() != null) {
        //     couponCacheService.cacheStock(coupon.getId(), request.getTotalCount());
        // }

        // 如果设置了生效时长，设置过期时间 - 已禁用
        // if (request.getValidHours() != null) {
        //     long expireSeconds = request.getValidHours() * 3600L;
        //     couponCacheService.setCouponExpire(coupon.getId(), expireSeconds);
        // }

        // 更新管理端优惠券列表缓存
        try {
            List<Coupons> allCoupons = this.list();
            adminCouponCacheService.cacheAdminCouponList(allCoupons);
            log.debug("优惠券创建后已更新coupons:admin:list缓存");
        } catch (Exception e) {
            log.warn("更新管理端优惠券缓存失败", e);
        }

        log.debug("优惠券创建完成，只保留coupons:键缓存");

        log.info("创建优惠券成功: {}", coupon.getId());
        return coupon.getId();
    }

    /**
     * 验证优惠券创建请求
     */
    private void validateCouponRequest(CouponCreateRequest request) {
        // 如果设置了生效时长，则为生效时长模式
        if (request.getValidHours() != null) {
            // 生效时长模式：validHours必须大于0，startTime和endTime可以为空
            if (request.getValidHours() <= 0) {
                throw new IllegalArgumentException("生效时长必须大于0小时");
            }
        } else {
            // 指定时间段模式：startTime和endTime不能为空
            if (request.getStartTime() == null) {
                throw new IllegalArgumentException("开始时间不能为空");
            }
            if (request.getEndTime() == null) {
                throw new IllegalArgumentException("结束时间不能为空");
            }
            // 验证时间逻辑
            if (request.getEndTime().before(request.getStartTime())) {
                throw new IllegalArgumentException("结束时间不能早于开始时间");
            }
        }
    }

    @Override
    @Transactional
    public Boolean updateCoupon(Integer id, CouponCreateRequest request) {
        // 验证优惠券是否存在
        Coupons existingCoupon = this.getById(id);
        if (existingCoupon == null) {
            throw new IllegalArgumentException("优惠券不存在");
        }

        // 验证优惠券请求
        validateCouponRequest(request);

        // 更新优惠券信息
        Coupons coupon = new Coupons();
        BeanUtils.copyProperties(request, coupon);
        coupon.setId(id);

        boolean success = this.updateById(coupon);

        if (success) {
            // 删除旧缓存
            couponCacheService.deleteCouponCache(id);

            // 重新缓存
            Coupons updatedCoupon = this.getById(id);
            couponCacheService.cacheCoupon(updatedCoupon);

            // 更新库存缓存
            if (request.getTotalCount() != null) {
                couponCacheService.cacheStock(id, request.getTotalCount());
            }

            log.info("更新优惠券成功: {}", id);
        }

        return success;
    }

    @Override
    @Transactional
    public Boolean deleteCoupon(Integer id) {
        // 验证优惠券是否存在
        Coupons coupon = this.getById(id);
        if (coupon == null) {
            throw new IllegalArgumentException("优惠券不存在");
        }

        // 检查是否有用户已领取
        // TODO: 检查用户优惠券表

        boolean success = this.removeById(id);

        if (success) {
            // 删除缓存
            couponCacheService.deleteCouponCache(id);
            log.info("删除优惠券成功: {}", id);
        }

        return success;
    }

    @Override
    public CouponVO getCouponDetail(Integer id) {
        // 先从缓存获取
        Coupons coupon = couponCacheService.getCachedCoupon(id);

        if (coupon == null) {
            // 缓存未命中，从数据库获取
            coupon = this.getById(id);
            if (coupon != null) {
                // 缓存到Redis
                couponCacheService.cacheCoupon(coupon);
            }
        }

        return coupon != null ? convertToVO(coupon) : null;
    }

    @Override
    @Transactional
    public Boolean activateCoupon(Integer id) {
        LambdaUpdateWrapper<Coupons> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Coupons::getId, id)
                .set(Coupons::getStatus, CouponStatus.ACTIVE.getCode());

        boolean success = this.update(updateWrapper);

        if (success) {
            // 删除旧的非coupons:键缓存 - 已禁用
            // couponCacheService.deleteCouponCache(id);

            // 更新管理端优惠券列表缓存
            try {
                List<Coupons> allCoupons = this.list();
                adminCouponCacheService.cacheAdminCouponList(allCoupons);
                log.debug("优惠券激活后已更新coupons:admin:list缓存");
            } catch (Exception e) {
                log.warn("更新管理端优惠券缓存失败", e);
            }

            log.info("激活优惠券成功: {}", id);
        }

        return success;
    }

    @Override
    @Transactional
    public Boolean deactivateCoupon(Integer id) {
        LambdaUpdateWrapper<Coupons> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Coupons::getId, id)
                .set(Coupons::getStatus, CouponStatus.INACTIVE.getCode());

        boolean success = this.update(updateWrapper);

        if (success) {
            // 删除旧的非coupons:键缓存 - 已禁用
            // couponCacheService.deleteCouponCache(id);

            // 更新管理端优惠券列表缓存
            try {
                List<Coupons> allCoupons = this.list();
                adminCouponCacheService.cacheAdminCouponList(allCoupons);
                log.debug("优惠券停用后已更新coupons:admin:list缓存");
            } catch (Exception e) {
                log.warn("更新管理端优惠券缓存失败", e);
            }

            log.info("停用优惠券成功: {}", id);
        }

        return success;
    }

    @Override
    public List<CouponVO> getActiveCoupons() {
        // 先尝试从coupons:admin:list缓存获取
        List<Coupons> cachedCoupons = adminCouponCacheService.getCachedAdminCouponList();
        if (cachedCoupons != null) {
            // 过滤出激活状态的优惠券
            List<CouponVO> voList = cachedCoupons.stream()
                    .filter(coupon -> coupon.getStatus().equals(CouponStatus.ACTIVE.getCode()))
                    .filter(coupon -> coupon.getStartTime() == null || !coupon.getStartTime().after(new Date()))
                    .filter(coupon -> coupon.getEndTime() == null || !coupon.getEndTime().before(new Date()))
                    .map(this::convertToVO)
                    .collect(Collectors.toList());
            log.debug("从coupons:admin:list缓存获取激活优惠券，数量: {}", voList.size());
            return voList;
        }

        // 缓存未命中，从数据库查询
        LambdaQueryWrapper<Coupons> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Coupons::getStatus, CouponStatus.ACTIVE.getCode())
                .le(Coupons::getStartTime, new Date())
                .ge(Coupons::getEndTime, new Date())
                .orderByDesc(Coupons::getId);

        List<Coupons> coupons = this.list(queryWrapper);
        List<CouponVO> voList = coupons.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 缓存所有优惠券到coupons:admin:list（包括激活和非激活的）
        List<Coupons> allCoupons = this.list();
        adminCouponCacheService.cacheAdminCouponList(allCoupons);

        return voList;
    }

    @Override
    @Transactional
    public void updateExpiredCoupons() {
        LambdaUpdateWrapper<Coupons> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.lt(Coupons::getEndTime, new Date())
                .eq(Coupons::getStatus, CouponStatus.ACTIVE.getCode())
                .set(Coupons::getStatus, CouponStatus.EXPIRED.getCode());

        boolean success = this.update(updateWrapper);

        if (success) {
            // 清除相关缓存
            couponCacheService.clearAllCouponCache();
            log.info("更新过期优惠券状态完成");
        }
    }

    @Override
    @Transactional
    public Boolean batchDeleteCoupons(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }

        boolean success = this.removeByIds(ids);

        if (success) {
            // 批量删除缓存
            for (Integer id : ids) {
                couponCacheService.deleteCouponCache(id);
            }
            log.info("批量删除优惠券成功: {}", ids);
        }

        return success;
    }

    /**
     * 转换为VO对象
     */
    private CouponVO convertToVO(Coupons coupon) {
        CouponVO vo = new CouponVO();
        BeanUtils.copyProperties(coupon, vo);

        // 设置类型名称
        CouponType type = CouponType.fromCode(coupon.getType());
        vo.setTypeName(type != null ? type.getDescription() : "未知");

        // 设置状态名称
        CouponStatus status = CouponStatus.fromCode(coupon.getStatus());
        vo.setStatusName(status != null ? status.getDescription() : "未知");

        // 计算是否即将过期（24小时内）
        if (coupon.getEndTime() != null) {
            long timeDiff = coupon.getEndTime().getTime() - System.currentTimeMillis();
            vo.setExpiringSoon(timeDiff > 0 && timeDiff <= 24 * 60 * 60 * 1000);
        }

        // 从缓存获取库存信息
        Integer stock = couponCacheService.getStock(coupon.getId());
        if (stock != null) {
            vo.setRemainingCount(stock);
            // 假设总数量存储在某个字段中，这里需要根据实际情况调整
            vo.setTotalCount(stock); // 临时设置，实际应该从数据库或其他地方获取
            vo.setUsedCount(0); // 临时设置
            vo.setUsageRate(0.0); // 临时设置
        }

        return vo;
    }
}




